package user

import (
	"beegoProject11/models/auth"
	"beegoProject11/utils"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"
	"github.com/astaxie/beego/orm"
	"math"
	"net/http"
	"strconv"
	"strings"
)

type UserController struct {
	beego.Controller
}

func (c *UserController) List() {

	o := orm.NewOrm()
	qs := o.QueryTable("sys_user")
	users := []auth.User{}

	// 每页显示数据-4条 (pagePerNum)
	pagePerNum := 2

	var count int64 = 0

	// 当前页 (currentPage)
	currentPage, err := c.GetInt("page")

	/*
		增加查询：
	*/
	offsetNum := pagePerNum * (currentPage - 1)

	kw := c.GetString("kw")

	/* 查询日志 */
	ret := fmt.Sprintf("当前页:%d,查询条件:%s", currentPage, kw)
	logs.Info(ret)

	if kw != "" { // 判断kw有查询条件的，那就会对总数和用户查询结果有影响
		// 总数据量--增加过滤username__contains
		count, _ = qs.Filter("is_delete", 0).Filter("username__contains", kw).Count()
		// 用户详细信息查询--增加过滤username__contains
		qs.Filter("is_delete", 0).Filter("username__contains", kw).Limit(pagePerNum).Offset(offsetNum).All(&users)
	} else {
		// 总数据量
		count, _ = qs.Filter("is_delete", 0).Count()
		// 用户详细信息查询
		qs.Filter("is_delete", 0).Limit(pagePerNum).Offset(offsetNum).All(&users)
	}

	// 总页数 (count) =  总数据量 / 每页数据量   注：需要转换成int类型
	countPage := int(math.Ceil(float64(count) / float64(pagePerNum)))
	fmt.Println("总数据量: !!!!!!!!!!!!!!!!!!!!", count)
	fmt.Println("每页数量: !!!!!!!!!!!!!!!!!!!!", pagePerNum)

	// err 当点击页面时候没有获取到当前页也就是null，所以默认显示第一页
	if err != nil {
		currentPage = 1
	}

	// 判断上一页
	prePage := 1
	if currentPage == 1 {
		prePage = currentPage
	} else if currentPage > 1 {
		// 上一页
		prePage = currentPage - 1
	}

	// 下一页
	nextPage := 1
	// 如果当前页小于总页数
	if currentPage < countPage {
		// 下一页 就等于 当前页+1
		nextPage = currentPage + 1
		// 如果当前页面大于等于总页数
	} else if currentPage >= countPage {
		// 下一页 就等于 当前页
		nextPage = currentPage
	}

	// 引用倒入到函数page.go
	page_map := utils.Paginator(currentPage, pagePerNum, count)
	c.Data["page_map"] = page_map

	c.Data["users"] = users
	c.Data["prePage"] = prePage /* 上一页*/
	fmt.Println("上一页: =============================> ", prePage)
	c.Data["nextPage"] = nextPage /* 下一页 */
	fmt.Println("下一页: =============================> ", nextPage)
	c.Data["currentPage"] = currentPage /* 当前页 */
	fmt.Println("当前页: =============================> ", currentPage)
	c.Data["countPage"] = countPage /* 总页数 */
	fmt.Println("总页数: =============================> ", countPage)
	c.Data["count"] = count
	c.Data["kw"] = kw
	c.TplName = "user/user-list.html"
}

func (c *UserController) ToAdd() {
	c.TplName = "user/user-add.html"
}

func (c *UserController) DoAdd() {
	/* 获取前端数据 */
	username := c.GetString("username")
	password := c.GetString("password")
	age, _ := c.GetInt("age")
	gender, _ := c.GetInt("gender")
	phone := c.GetString("phone")
	addr := c.GetString("addr")
	isActive, _ := c.GetInt("is_active")

	/* 密码转换 */
	new_password := utils.Md5Text(password)

	/* phone转换int64 */
	phone_int64, _ := strconv.ParseInt(phone, 10, 64)

	/* 初始化数据库 */

	o := orm.NewOrm()
	user_data := auth.User{
		UserName: username,
		Password: new_password,
		Age:      age,
		Gender:   gender,
		Phone:    phone_int64,
		Addr:     addr,
		IsActive: isActive,
	}

	/* 返回到前端ajax到数据 */
	messageMap := map[string]interface{}{}

	/* 数据库插入数据 */
	_, err := o.Insert(&user_data)

	if err != nil {
		/* 数据添加错误日志 */
		dateRet := fmt.Sprintf("添加数据信息:userName:%s;md5Pwd:%s;Age:%d;Gender:%d;Phone:%s;Addr:%s,isAcitve:%s",
			username, new_password, age, gender, phone, addr, isActive)
		ret := fmt.Sprintf("添加数据错误，错误信息:%v", err)
		logs.Error(dateRet)
		logs.Error(ret)
		messageMap["code"] = 10001
		messageMap["msg"] = "添加数据出错,请重新添加!"
		c.Data["json"] = messageMap
	} else {
		/* 数据添加正确日志 */
		dateRet := fmt.Sprintf("插入数据成功，数据信息:userName:%s;md5Pwd:%s;Age:%d;Gender:%d;Phone:%s;Addr:%s,isAcitve:%s",
			username, new_password, age, gender, phone, addr, isActive)
		logs.Info(dateRet)
		messageMap["code"] = 200
		messageMap["msg"] = "添加成功!"
		c.Data["json"] = messageMap
	}

	c.ServeJSON()
}

func (c *UserController) IsActive() {
	// 获取数据
	isActive, _ := c.GetInt("is_active_val")
	id, _ := c.GetInt("id")

	// 初始化数据库
	o := orm.NewOrm()
	qs := o.QueryTable("sys_user").Filter("id", id)

	// 初始化返回数据
	messageMap := map[string]interface{}{}

	// 判断isActive，使用qs.Update更新
	if isActive == 1 {
		qs.Update(orm.Params{
			"is_active": 0,
		})
		/* 停用成功日志 */
		ret := fmt.Sprintf("用户id:%d，停用成功", id)
		logs.Info(ret)
		messageMap["msg"] = "停用成功"
	} else if isActive == 0 {
		qs.Update(orm.Params{
			"is_active": 1,
		})
		/* 启用成功日志 */
		ret := fmt.Sprintf("用户id:%d，启用成功", id)
		logs.Info(ret)
		messageMap["msg"] = "启用成功"
	}
	c.Data["json"] = messageMap
	c.ServeJSON()
}

func (c *UserController) Delete() {
	id, _ := c.GetInt("id")

	o := orm.NewOrm()
	o.QueryTable("sys_user").Filter("id", id).Update(orm.Params{
		"is_delete": 1,
	})
	c.Redirect(beego.URLFor("UserController.List"), http.StatusFound)
}

func (c *UserController) ResetPassword() {
	id, _ := c.GetInt("id")

	newPwd := utils.Md5Text("123456")

	o := orm.NewOrm()
	o.QueryTable("sys_user").Filter("id", id).Update(orm.Params{
		"password": newPwd,
	})
	/* 重置密码日志 */
	ret := fmt.Sprintf("用户id:%d,重置密码成功", id)
	logs.Info(ret)
	c.Redirect(beego.URLFor("UserController.List"), http.StatusFound)
}

func (c *UserController) ToUpdate() {

	// 获取前端数据
	id, _ := c.GetInt("id")
	o := orm.NewOrm()
	userData := auth.User{}
	o.QueryTable("sys_user").Filter("id", id).One(&userData)

	c.Data["user"] = userData

	/* 修改用户信息日志 */
	ret := fmt.Sprintf("用户信息修改，用户id:%d", id)
	logs.Info(ret)

	c.TplName = "user/user-edit.html"
}

func (c *UserController) DoUpdate() {
	/* 获取前端数据 */
	uid, _ := c.GetInt("uid")
	username := c.GetString("username")
	password := c.GetString("password")
	age, _ := c.GetInt("age")
	gender, _ := c.GetInt("gender")
	phone := c.GetString("phone")
	addr := c.GetString("addr")
	isActive, _ := c.GetInt("is_active")

	o := orm.NewOrm()

	qs := o.QueryTable("sys_user").Filter("id", uid)

	// 返回结果初始化
	messageMap := map[string]interface{}{}

	// 密码加密
	newPwd := utils.Md5Text(password)

	if password == "" {
		// 增加错误判断获取返回给前端
		_, err := qs.Update(orm.Params{
			"username":  username,
			"age":       age,
			"gender":    gender,
			"phone":     phone,
			"addr":      addr,
			"is_active": isActive,
		})
		// 判断数据库是否有错误并返回前端
		if err != nil {
			ret := fmt.Sprintf("更新失败，用户id:%d", uid)
			logs.Error(ret)
			messageMap["code"] = 10001
			messageMap["msg"] = "更新失败"
		} else {
			ret := fmt.Sprintf("更新成功，用户id:%d", uid)
			logs.Info(ret)
			messageMap["code"] = 200
			messageMap["msg"] = "更新成功"
		}
	} else {
		// 增加错误判断获取返回给前端
		_, err := qs.Update(orm.Params{
			"username":  username,
			"password":  newPwd,
			"age":       age,
			"gender":    gender,
			"phone":     phone,
			"addr":      addr,
			"is_active": isActive,
		})
		if err != nil {
			ret := fmt.Sprintf("更新失败，用户id:%d", uid)
			logs.Error(ret)
			messageMap["code"] = 10001
			messageMap["msg"] = "更新失败"
		} else {
			ret := fmt.Sprintf("更新成功，用户id:%d", uid)
			logs.Info(ret)
			messageMap["code"] = 200
			messageMap["msg"] = "更新成功"
		}
	}

	c.Data["json"] = messageMap
	c.ServeJSON()

}

func (c *UserController) MuLiDelete() {
	ids := c.GetString("ids")

	// 去除双引号 "3,7,8"
	newIds := ids[1 : len(ids)-1]

	// 字符串切割 "3,7,8"
	idArr := strings.Split(newIds, ",")

	// 数据库
	o := orm.NewOrm()
	qs := o.QueryTable("sys_user")

	//循环提取idArr-注意是字符串需要转int
	for _, v := range idArr {
		// 字符串转换成int
		intId, _ := strconv.Atoi(v)
		// 查找对应的ID
		qs.Filter("id", intId).Update(orm.Params{
			"is_delete": 1,
		})
	}

	ret := fmt.Sprintf("批量删除成功，用户ids:%d", ids)
	logs.Info(ret)

	c.Data["json"] = map[string]interface{}{
		"code": 200,
		"msg":  "批量删除成功",
	}
	c.ServeJSON()
}
